// Copyright (C) <2018> Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0

'use strict';

// Please change example.com to signaling server's address.
const serverAddress = "http://192.168.137.130:8095";
let isConn = false;

// Please change this STUN and TURN server information.
const rtcConfiguration = {
  iceServers: [
    {
      urls: 'stun:119.97.143.86:3478',
    },
    {
      urls: [
        'turn:119.97.143.86:3478'
      ],
      credential: '1234',
      username: 'admin',
    }
  ],
  // "iceTransportPolicy": "relay"
};

const signaling = new SignalingChannel();
let publicationForCamera;
const p2p = new Owt.P2P.P2PClient({
  audioEncodings: true,
  videoEncodings: [{
    codec: {
      name: 'h264',
    },
  }
    , {
    codec: {
      name: 'vp9',
    },
  }
    , {
    codec: {
      name: 'vp8',
    },
  }
  ],
  rtcConfiguration
}, signaling);

let localStream;
let screenStream;
let statsTask;

let videoSize = {
  width: 0,
  height: 0
};
let resolution = {
  width: 0,
  height: 0
};
const getTargetId = function () {
  return $('#remote-uid').val();
};

$(document).ready(function () {
  $('#set-remote-uid').click(function () {
    p2p.allowedRemoteIds = [getTargetId()];
  });

  $('#mute-toggle').click(function () {
    document.getElementById('remoteVideo').muted = !document.getElementById('remoteVideo').muted;
    document.getElementById('screenVideo').muted = !document.getElementById('screenVideo').muted;
  });

  $('#target-screen').click(function () {
    const config = {
      audio: {
        source: 'screen-cast',
      },
      video: {
        source: 'screen-cast',
      },
    };
    let mediaStream;
    Owt.Base.MediaStreamFactory.createMediaStream(config).then(
      (stream) => {
        mediaStream = stream;
        screenStream = new Owt.Base.LocalStream(mediaStream, new Owt
          .Base.StreamSourceInfo('screen-cast', 'screen-cast'));
        $('#local').children('video').get(0).srcObject = screenStream
          .mediaStream;
        p2p.publish(getTargetId(), screenStream).then(
          (publication) => { }), (error) => {
            console.log('Failed to share screen.');
          };
      }, (err) => {
        console.error('Failed to create MediaStream, ' + err);
      });
  });

  $('#target-video-unpublish').click(function () {
    $('#target-video-publish').prop('disabled', false);
    $('#target-video-unpublish').prop('disabled', true);
    publicationForCamera.stop();
    for (const track of localStream.mediaStream.getTracks()) {
      track.stop();
    }
    localStream = undefined;
  });

  $('#target-video-publish').click(function () {
    $('#target-video-unpublish').prop('disabled', false);
    $('#target-video-publish').prop('disabled', true);
    if (localStream) {
      p2p.publish(getTargetId(), localStream).then((publication) => {
        publicationForCamera = publication;
      }, (error) => {
        console.log('Failed to share video.');
      }); // Publish local stream to remote client
    } else {
      const audioConstraintsForMic = new Owt.Base.AudioTrackConstraints(
        Owt.Base.AudioSourceInfo.MIC);
      const videoConstraintsForCamera = new Owt.Base
        .VideoTrackConstraints(Owt.Base.VideoSourceInfo.CAMERA);
      let mediaStream;
      Owt.Base.MediaStreamFactory.createMediaStream(new Owt.Base
        .StreamConstraints(audioConstraintsForMic,
          videoConstraintsForCamera)).then((stream) => {
            mediaStream = stream;
            localStream = new Owt.Base.LocalStream(mediaStream, new Owt
              .Base.StreamSourceInfo('mic', 'camera'));
            $('#local').children('video').get(0).srcObject = localStream
              .mediaStream;
            p2p.publish(getTargetId(), localStream).then(
              (publication) => {
                publicationForCamera = publication;
              }, (error) => {
                console.log('Failed to share video.');
              });
          }, (err) => {
            console.error('Failed to create MediaStream, ' + err);
          });
    }
  });

  $('#target-peerconnection-stop').click(function () {
    p2p.stop(getTargetId()); // Stop conversation
  });

  $('#login').click(function () {
    p2p.connect({
      host: serverAddress,
      token: $('#uid').val(),
    }).then(() => {
      isConn = true;

      $('#uid').prop('disabled', true);
    }, (error) => {
      console.log('Failed to connect to the signaling server.');
    }); // Connect to signaling server.
  });

  $('#logoff').click(function () {
    p2p.disconnect();
    isConn = false;
    $('#uid').prop('disabled', false);
  });

  $('#data-send').click(function () {
    p2p.send(getTargetId(), $('#dataSent').val()); // Send data to remote endpoint.
  });
});

p2p.addEventListener('streamadded',
  function (e) { // A remote stream is available.
    e.stream.addEventListener('ended', () => {
      clearInterval(statsTask);
      $('#control').show();
      $('#sendreceive').show();
      $('#local').show();
      $('#stats').hide();
      console.log('Stream is removed.');
    });
    resolution.width = $('#remoteVideo').width();
    resolution.height = $('#remoteVideo').height();
    var data = {
      event: 'size',
      w: resolution.width,
      h: resolution.height
    };
    p2p.send(getTargetId(), JSON.stringify(data));

    $('#control').hide();
    $('#sendreceive').hide();
    $('#local').hide();
    $('#stats').show();
    if (e.stream.source.audio || e.stream.source.video) {
      $('#remoteVideo').show();
      $('#remoteVideo').get(0).srcObject = e.stream.mediaStream;
      $('#remoteVideo').get(0).play();
      $('#remoteVideo').get(0).muted = false;
    }

    statsTask = setInterval(() => {
      p2p.getStats(getTargetId()).then(statsResult => {
        statsResult.forEach(stats => {

          if (stats.type === 'inbound-rtp' && stats.kind === 'video') {
            console.log(stats)
            let txt = `
            <p>fps:${stats.framesPerSecond}</p>
            <p>frameSize:${stats.frameWidth}x${stats.frameHeight}</p>
            <p>framesReceived:${stats.framesReceived},framesDecoded:${stats.framesDecoded}</p>
            <p>jitter:${stats.jitter}</p>
            <p>jitterBufferDelay:${stats.jitterBufferDelay / (stats.jitterBufferEmittedCount / 1000)}</p>
            <p>packetsLost:${stats.packetsLost}</p>
            <p>totalDecodeTime:${stats.totalDecodeTime}</p>
            `;
            $('#stats').html(txt);
          }
        });

      })


    }, 1000);


  });

p2p.addEventListener('messagereceived',
  function (e) { // Received data from datachannel.
    $('#dataReceived').val(e.origin + ': ' + e.message);
  });



window.onbeforeunload = function () {
  p2p.stop(getTargetId());
};

// document.getElementById('remoteVideo').addEventListener("click",e=>{
//   console.log(e);
// });


$(() => {
  var video = document.getElementById('remoteVideo');
  video.addEventListener('mousemove', e => {
    var data = {
      type: 'mousemove',
      x: e.offsetX,
      y: e.offsetY
    }
    if (isConn) {
      //p2p.send(getTargetId(),JSON.stringify(data));
    }
  });
});